package othello.shared.model;

import java.io.Serializable;

import org.slim3.datastore.Attribute;
import org.slim3.datastore.Model;

import com.google.appengine.api.datastore.Key;

/**
 * <p>
 * ゲームのステップ情報です。
 * </p>
 * 以下の情報を保持します。
 * <ul>
 * <li>ステップ数</li>
 * <li>手番（白、黒）</li>
 * <li>配置場所</li>
 * </ul>
 * 
 * @author onjiro.mohyahya
 */
@SuppressWarnings("serial")
@Model(schemaVersion = 1)
public class GameStep implements Serializable {

	/**
	 * コマの白、黒を表す
	 */
	public static enum Side {
		Black, White, None
	}

	@Attribute(primaryKey = true)
	private Key key;

	@Attribute(version = true)
	private Long version;

	/**
	 * ステップ数
	 */
	private int stepNumber;

	/**
	 * 白 or 黒
	 */
	private GameStep.Side side;

	/**
	 * 配置場所 - x
	 */
	private int x;

	/**
	 * 配置場所 - y
	 */
	private int y;

	/**
	 * <p>
	 * デフォルト・コンストラクター
	 * </p>
	 * データストアからの生成に必要（多分）
	 */
	public GameStep() {
	}

	/**
	 * 必要な要素を指定するコンストラクター
	 * 
	 * @param side
	 * @param x
	 * @param y
	 * @param stepNumber
	 */
	public GameStep(GameStep.Side side, int x, int y, int stepNumber) {
		this.side = side;
		this.x = x;
		this.y = y;
		this.stepNumber = stepNumber;
	}

	/**
	 * Returns the key.
	 * 
	 * @return the key
	 */
	public Key getKey() {
		return key;
	}

	/**
	 * Sets the key.
	 * 
	 * @param key
	 *            the key
	 */
	public void setKey(Key key) {
		this.key = key;
	}

	/**
	 * Returns the version.
	 * 
	 * @return the version
	 */
	public Long getVersion() {
		return version;
	}

	/**
	 * Sets the version.
	 * 
	 * @param version
	 *            the version
	 */
	public void setVersion(Long version) {
		this.version = version;
	}

	public int getStepNumber() {
		return stepNumber;
	}

	public GameStep.Side getSide() {
		return side;
	}

	public int getX() {
		return x;
	}

	public int getY() {
		return y;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((key == null) ? 0 : key.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		GameStep other = (GameStep) obj;
		if (key == null) {
			if (other.key != null) {
				return false;
			}
		} else if (!key.equals(other.key)) {
			return false;
		}
		return true;
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append(this.stepNumber).append(":").append(this.side);
		sb.append("(").append(this.x).append(",").append(this.y).append(")");
		return sb.toString();
	}
}
